package com.acme;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;


public class Analyzer {

	public static void main(final String[] args) {
		StringBuffer sb = new StringBuffer();
		
		Class<Test> clazz = Test.class;
		String name = clazz.getName();
		sb.append(String.format("Class name: %s\n", name));
		
		sb.append("Modifiers:");
		int modifiers = clazz.getModifiers();
		if(Modifier.isAbstract(modifiers)) {
			sb.append(" abstract");
		}
		if(Modifier.isFinal(modifiers)) {
			sb.append(" final");
		}
		if(Modifier.isInterface(modifiers)) {
			sb.append(" interface");
		}
		
		String superClassName = clazz.getSuperclass().getName();
		sb.append(String.format("\nSuper class: %s", superClassName));
		
		Class[] interfaces = clazz.getInterfaces();
		sb.append("\nInterfaces: ");
		for(Class<?> cl: interfaces) {
			sb.append(cl.getName() + " ");
		}
		
		sb.append("\nFields: ");
		Field[] fields = clazz.getFields();
		for(Field f: fields) {
			sb.append(f.getName() + " ");
		}
		
		sb.append("\nMethods:\n");
		Method[] methods = clazz.getMethods();
		for(Method m: methods) {
			sb.append("=================================\n");
			sb.append(String.format("\tName: %s\n", m.getName()));
			
			Annotation[] annotations = m.getAnnotations();
			sb.append("\tAnnotations:\n");
			for(Annotation a: annotations) {
				sb.append(String.format("\t\t* %s\n", a.toString()));
			}
			
			Annotation[][] paramAnnotations = m.getParameterAnnotations();
			sb.append("\n\tMethod annotation:\n");
			for(Annotation[] ann: paramAnnotations) {
				sb.append(String.format("\t\t* %s\n", ann.toString()));
			}
			
			Class[] exceptionTypes = m.getExceptionTypes();
			sb.append("\tMethod exceptions:\n");
			for(Class<?> cl: exceptionTypes) {
				sb.append(String.format("\t\t* %s\n", cl.getName()));
			}
			
			sb.append("\n");
		}
		System.out.println(sb.toString());
	}
}
